﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace SiaNet.Engine
{
    public class BackendUtil
    {
        public static IEnumerable<Tuple<int, int>> SwapsForReordering(int[] perm)
        {
            int j;
            for (int i = 0; i < perm.Length; ++i)
            {
                var p = perm[i];
                if (p != i && p != -1)
                {
                    j = i;
                    do
                    {
                        if (perm[j] < 0 || perm[j] >= perm.Length)
                            throw new InvalidOperationException("Invalid permutation");

                        yield return Tuple.Create(j, perm[j]);

                        var jOld = j;
                        j = perm[j];
                        perm[jOld] = -1;
                    } while (perm[j] != i);
                    perm[j] = j;
                }
            }
        }

        public static int[] CastShapeInt(long[] shape, bool reverse = false)
        {
            if (reverse)
                shape = shape.Reverse().ToArray();

            return Array.ConvertAll(shape, x => (int)x);
        }

        public static uint[] CastShapeUInt(long[] shape, bool reverse = false)
        {
            if (reverse)
                shape = shape.Reverse().ToArray();

            return Array.ConvertAll(shape, x => (uint)x);
        }

        public static uint[] CastShapeUInt(int[] shape, bool reverse = false)
        {
            if (reverse)
                shape = shape.Reverse().ToArray();

            return Array.ConvertAll(shape, x => (uint)x);
        }

        public static long[] Int2Long(int[] shape)
        {
            return Array.ConvertAll(shape, x => (long)x);
        }

        public static void Print(long[] shape, Array data)
        {
            var rank = data.Rank;
        }

        public static long[] Row2ColMajor(long[] shape)
        {
            long[] result = null;

            if(shape.Length == 4)
            {
                result = new long[4];
                result[0] = shape[0];
                result[1] = shape[2];
                result[2] = shape[3];
                result[3] = shape[1];
            }
            else if (shape.Length == 5)
            {
                result = new long[4];
                result[0] = shape[0];
                result[1] = shape[3];
                result[2] = shape[4];
                result[3] = shape[1];
                result[3] = shape[2];
            }
            else
            {
                result = shape;
            }

            return result;
        }

        public static long[] Col2RowMajor(long[] shape)
        {
            long[] result = null;

            if (shape.Length == 4)
            {
                result = new long[4];
                result[0] = shape[0];
                result[1] = shape[3];
                result[2] = shape[1];
                result[3] = shape[2];
            }
            else if (shape.Length == 5)
            {
                result = new long[4];
                result[0] = shape[0];
                result[1] = shape[3];
                result[2] = shape[4];
                result[3] = shape[1];
                result[3] = shape[2];
            }
            else
            {
                result = shape;
            }

            return result;
        }
    }
}
